package cn.edu.sdjzu.xg.eagle.Controller;

import cn.edu.sdjzu.xg.eagle.Service.UserService;
import cn.edu.sdjzu.xg.eagle.entity.User;
import cn.edu.sdjzu.xg.eagle.exception.BaseException;
import cn.edu.sdjzu.xg.eagle.factory.ServiceFactory;
import cn.edu.sdjzu.xg.eagle.util.JSONUtil;
import com.alibaba.fastjson2.JSONObject;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.io.IOException;
import java.sql.SQLException;
import java.util.Date;
import java.util.logging.Logger;
import com.auth0.jwt.JWT;               // 导入 JWT 类
import com.auth0.jwt.algorithms.Algorithm; // 导入 Algorithm 类

import javax.naming.AuthenticationException;


@WebServlet("/login")
public class LoginCtl extends HttpServlet {

    private static final Logger logger = Logger.getLogger(LoginCtl.class.getName());

    //秘钥
    private static final String SECRET_KEY = "XG23";
    //Token有效期
    private static final long TOKEN_EXPIRATION_TIME = 30*60*1000;

    private final JwTokenGenerator jwTokenGenerator = new JwTokenGenerator(SECRET_KEY,TOKEN_EXPIRATION_TIME);

    private final ResponseHandler responseHandler = new ResponseHandler();

    private UserService userService;

    public void init() throws ServletException {
        try {
            // 获取service实例对象
            userService = ServiceFactory.getService(UserService.class,"UserService");
        } catch (BaseException e) {
            throw new ServletException("初始化UserService失败:" + e.getMessage());
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

        request.setCharacterEncoding("utf-8");

        try {
            //构建 User 对象
            User userToLogin = parseUserRequest(request);
            //验证用户合法性
            validateUserCredentials(userToLogin);
            //构建令牌
            String token = jwTokenGenerator.generateToken(userToLogin.getId());
            //根据令牌做出响应
            responseHandler.sendSuccessResponse(response,token);

        } catch (IllegalArgumentException e) {
            logger.warning("无效的请求参数:" + e.getMessage());
            responseHandler.sendErrorResponse(response,e.getMessage(),400);
        } catch (AuthenticationException e) {
            logger.warning("认证失败:" + e.getMessage());
            responseHandler.sendErrorResponse(response,e.getMessage(),401);
        } catch (SQLException e) {
            logger.warning("数据库操作异常:" + e.getMessage());
            responseHandler.sendErrorResponse(response,"数据库操作异常",500);
        } catch (Exception e) {
            logger.warning("系统异常" + e.getMessage());
            responseHandler.sendErrorResponse(response,"系统异常",500);
        }


    }
    //解析用户请求
    private User parseUserRequest(HttpServletRequest request) throws IOException {
        String userJson = JSONUtil.getJSON(request);
        User userToLogin = JSONObject.parseObject(userJson, User.class);

        if (userToLogin == null || userToLogin.getUsername() == null || userToLogin.getPassword() == null) {
            throw new IllegalArgumentException("请求参数不完整");
        }
        return userToLogin;
    }
    //校验用户凭证
    private void validateUserCredentials(User user) throws SQLException, AuthenticationException {
        userService.login(user);
        if (user.getId() == null) {
            throw new BaseException("用户不存在/密码错误");
        }
    }

    private static class JwTokenGenerator {

        private final String secretKey;
        private final long tokenExpirationTime;

        public JwTokenGenerator(String secretKey, long tokenExpirationTime) {
            this.secretKey = secretKey;
            this.tokenExpirationTime = tokenExpirationTime;
        }

        public String generateToken(long userId) {
            return JWT.create()
                    .withSubject(String.valueOf(userId))
                    .withExpiresAt(new Date(System.currentTimeMillis() + tokenExpirationTime))
                    .sign(Algorithm.HMAC256(secretKey));

        }
    }

    private static final class ResponseHandler {
        //登录成功的消息
        public void sendSuccessResponse(HttpServletResponse response,String token) throws IOException {

            JSONObject responseBody = new JSONObject();
            responseBody.put("message","登录成功");
            responseBody.put("code",200);
            responseBody.put("token",token);
            sendResponse(response,responseBody);

        }

        //登录失败的消息
        public void sendErrorResponse(HttpServletResponse response,String errorMsg,int statuesCode) throws IOException {
            try {
                JSONObject responseBody = new JSONObject();
                responseBody.put("message",errorMsg);
                responseBody.put("code",statuesCode);
                response.setStatus(statuesCode);
                sendResponse(response,responseBody);
            } catch (IOException e) {
                logger.warning("发送错误请求失败" + e.getMessage());
            }
        }
        private void sendResponse(HttpServletResponse response,JSONObject responseBody) throws IOException {
            response.getWriter().write(responseBody.toJSONString());
        }
    }


}
